package web.advice;


import Utils.UserContext;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import web.annotation.Current;
import web.annotation.CurrentSchoolId;
import web.annotation.CurrentUserId;
import web.annotation.CurrentUserName;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;

@ControllerAdvice
@Slf4j
public class CurrentBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return methodParameter.hasParameterAnnotation(Current.class) ;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        return httpInputMessage;
    }

    @SneakyThrows
    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        if (o != null) {
            Class clazz = o.getClass();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(CurrentSchoolId.class)) {
                    field.setAccessible(true);
                    field.set(o, UserContext.getUserHolder().getSchoolId());
                }
                if (field.isAnnotationPresent(CurrentUserName.class)) {
                    field.setAccessible(true);
                    field.set(o, UserContext.getUserHolder().getRealName());

                }
                if (field.isAnnotationPresent(CurrentUserId.class)) {
                    field.setAccessible(true);
                    field.set(o, UserContext.getUserHolder().getUserId());
                }
            }
        }
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
}
